bondscell_results$334abd5f-8a2c-4e05-96cc-feb9dd8f30aequeued¤logsrunning¦outputbodyF

1: Function Syntax (Multi-line & Defaults)

mimetext/htmlrootassigneelast_run_timestampA}Q~ڰpersist_js_state·has_pluto_hook_features§cell_id$334abd5f-8a2c-4e05-96cc-feb9dd8f30aedepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$afe988c7-c708-4fdb-bf82-54edeb9db708queued¤logsrunning¦outputbodyٟ

1-4: Functions

Last Updated: 2 May 2026

mimetext/htmlrootassigneelast_run_timestampA}QG persist_js_state·has_pluto_hook_features§cell_id$afe988c7-c708-4fdb-bf82-54edeb9db708depends_on_disabled_cells§runtimeHNpublished_object_keysdepends_on_skipped_cells§errored$c78da21b-40ad-42d1-8516-b91d16982c77queued¤logsrunning¦outputbody

Functions in Julia

Introduction to the contruction of Julia functions and their implementation by Julia.

If you come from Python or Java, functions are attached to classes. In Julia, functions are standalone citizens, and they define the behavior of the language. We will cover the syntax, the argument system, and introduce a key Julia feature: multiple dispatch.

mimetext/htmlrootassigneelast_run_timestampA}Q~persist_js_state·has_pluto_hook_features§cell_id$c78da21b-40ad-42d1-8516-b91d16982c77depends_on_disabled_cells§runtimeZLpublished_object_keysdepends_on_skipped_cells§errored$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76dqueued¤logsrunning¦outputbody

6: Function Broadcasting

mimetext/htmlrootassigneelast_run_timestampA}Q~a,persist_js_state·has_pluto_hook_features§cell_id$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76ddepends_on_disabled_cells§runtime Xpublished_object_keysdepends_on_skipped_cells§errored$09abe51d-ed7d-4f8a-b49c-193dbf188e02queued¤logsrunning¦outputbody9

Summary

mimetext/htmlrootassigneelast_run_timestampA}Q~persist_js_state·has_pluto_hook_features§cell_id$09abe51d-ed7d-4f8a-b49c-193dbf188e02depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$0659caa1-1dfd-418a-80c8-3167ca30ade9queued¤logsrunning¦outputbody4

2: Keywords & Single-liners

mimetext/htmlrootassigneelast_run_timestampA}Q~Npersist_js_state·has_pluto_hook_features§cell_id$0659caa1-1dfd-418a-80c8-3167ca30ade9depends_on_disabled_cells§runtimel:published_object_keysdepends_on_skipped_cells§errored$12928360-90aa-4409-860a-af7f5c781e98queued¤logsrunning¦outputbody

Multiple Dispatch

The most important part and a core reason for Julia's existence.

Single Dispatch

Object-oriented languages such as Python and Java use single dispatch for choosing the function or method to execute. That means that the function is determined using the function name and the type of the first argument. This is called single dispatch. Therefore, the functions or methods are tightly bound to the object or class. When you call obj.method(arg), the language transforms that expression into method(obj, arg).

Single dispatch creates the Expression Problem. For example, a + b calls a.__add__(b) in Python. If the object a is known, but not b, there is no problem; the __add__ function can still be called. However, if a is unknown, what do we do now? In Python this problem is solved by the __radd__ function. Python will try __add__, if that fails, then it will try __radd__. Therefore, when we add an __add__ operator to a new class in Python, the new class must implement the __radd__ method too, because other classes do not know about our new classs.

Multiple Dispatch

Julia is not an object-oriented language. It is functional language. When you call func(arg1, arg2), Julia looks at the types of the function's positional arguments to determine the version of the function to execute. This is called multiple dispatch. Julia will look at the argument types of all positional arguments, i.e., arg1 and arg2, and choose the function that has that exact type signature. Multiple dispatch makes it easier for a new Julia type to extend the functional interface of another type.

The example below illustrates that situation. Two fAdd functions are implemented, one for each situation. Julia then determines which version of that function to execute. The situation is similar to Python's __add__ and __radd__, except that Python first tries to use __add__ and when that fails, tries __radd__. Whereas, Julia just chooses the correct function the first time. The following is an example of how Julia may implement this situation.

julia> # Define additon for an integer and a float, and the other way around:
julia> fAdd(a::Int, b::Float64) = a + b
julia> fAdd(a::Float64, b::Int) = a + b

Why is this powerful?

  1. Symmetry: You don't need radd because compared with (a::Float, b::Int), (a::Int, b::Float) is just a different method.

  2. Extensibility: If you import a library that defines a Planet type, and another library that defines a Satellite type, you can define a collide(p::Planet, s::Satellite) function in your own code without modifying the source code of either library.

  3. Trying to add two integers or two floating points fails, e.g., "ERROR: MethodError: no method matching fAdd(::Float64, ::Float64)." If you know, for example, that a particular function is only supposed to be called with an integer and a float, and you don't want to worry about the order, you now have a check on your code.

mimetext/htmlrootassigneelast_run_timestampA}Q~Vpersist_js_state·has_pluto_hook_features§cell_id$12928360-90aa-4409-860a-af7f5c781e98depends_on_disabled_cells§runtimeԵpublished_object_keysdepends_on_skipped_cells§errored$8e6406dd-e58c-4aef-8bc9-a57984f90884queued¤logsrunning¦outputbody

Problems

Remember that you can get help either through `?` in a REPL or with "Live Docs" right here in Pluto (lower right-hand corner)

mimetext/htmlrootassigneelast_run_timestampA}Q~persist_js_state·has_pluto_hook_features§cell_id$8e6406dd-e58c-4aef-8bc9-a57984f90884depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$70b70576-0c49-4e5b-b7c1-dd400f3fbccaqueued¤logsrunning¦outputbodyj

Function Arguments

Positional and Keyword

Functions have two types of arguments, positional and keyword. They are separated using a ';' (semi-colon). Positional arguments are required, whereas keyword arguments are optional. The next section will show the importance of positional arguments.

julia> # a and b are positional, while scale and offset are keywords
julia> function transform(a, b; scale=1.0, offset=0.0)
    return (a + b) * scale + offset
end

julia> # Usage
julia> transform(10, 20; scale=2.0)

Default Values and Methods

Positional arguments can have default values, which means the default value will be used if the argument is missing.

julia> # This function defines a default value for the y.
julia> myfunc(x, y=10) = x * y

Julia creates two versions or methods of this function, one with two arguments and one with one argument.

julia> myfunc(x, y)
julia> myfunc(x)    # The 2nd positional argument will have the value 10.
mimetext/htmlrootassigneelast_run_timestampA}Q~۰persist_js_state·has_pluto_hook_features§cell_id$70b70576-0c49-4e5b-b7c1-dd400f3fbccadepends_on_disabled_cells§runtimehpublished_object_keysdepends_on_skipped_cells§errored$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7queued¤logsrunning¦outputbody.

5: Specialization & Dispatch

mimetext/htmlrootassigneelast_run_timestampA}Q~"lpersist_js_state·has_pluto_hook_features§cell_id$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7depends_on_disabled_cells§runtimeDpublished_object_keysdepends_on_skipped_cells§errored$c74cace1-0e96-48e7-82d3-12f3af3d8591queued¤logsrunning¦outputbody

Defining Functions

Julia offers three syntactic ways to define a function. They all compile down to the same code, so choose the syntax that is most convenient or appropriate.

Default Syntax

The standard multi-line version looks similar to other languages. It uses the function statement and closes with the end statement.

julia> function hypotenuse(a, b)
    result = sqrt(a^2 + b^2)
    return result
end

Note

Single-Line Syntax

The single-line assignment form may be unique to Julia and is perfect for short operations. While functionally identical to the multiline version, it reduces visual clutter for simple logic.

julia> hypotenuse(a, b) = sqrt(a^2 + b^2)

Note

The compiler will automatically inline functions to improve performance, unlike C or Python. Therefore, there is no performance hit by using functions and their use is encouraged for convenience and readability.

Anonymous Functions (Lambdas)

An anonymous function uses the arrow syntax: ->. The variables before the -> are the arguments to be used and the expression afterward is the function body. They are often used in functional programming contexts such as map, filter or findall to define a filter.

julia> # Equivalent to Python's: lambda x: x^2 + 2x - 1
julia> f = x -> x^2 + 2x - 1

julia> # Usage in a map function
julia> map(x -> x^2, [1, 2, 3])

julia> # Two arrays zipped together returning a Tuple with two values.
julia> map(((x, y),) -> x > 2 && y > 4, zip(1:5, 2:6))
mimetext/htmlrootassigneelast_run_timestampA}Q~cxpersist_js_state·has_pluto_hook_features§cell_id$c74cace1-0e96-48e7-82d3-12f3af3d8591depends_on_disabled_cells§runtimekpublished_object_keysdepends_on_skipped_cells§errored$50f84dd5-7585-482d-bd8e-96b6cabfdbc2queued¤logsrunning¦outputbody

3: Anonymous Functions (Map & Filter)

mimetext/htmlrootassigneelast_run_timestampA}Q~‡°persist_js_state·has_pluto_hook_features§cell_id$50f84dd5-7585-482d-bd8e-96b6cabfdbc2depends_on_disabled_cells§runtime jipublished_object_keysdepends_on_skipped_cells§errored$a1ec03ac-f7b4-4499-92e2-c2a047ed3574queued¤logsrunning¦outputbody

4: The Generic add()

mimetext/htmlrootassigneelast_run_timestampA}Q~ӿpersist_js_state·has_pluto_hook_features§cell_id$a1ec03ac-f7b4-4499-92e2-c2a047ed3574depends_on_disabled_cells§runtimeϵpublished_object_keysdepends_on_skipped_cells§errored$d8ba51b9-2d28-4d97-8704-c56c44e04a62queued¤logsrunning¦outputbody

Summary of Dispatch

mimetext/htmlrootassigneelast_run_timestampA}Q~fbpersist_js_state·has_pluto_hook_features§cell_id$d8ba51b9-2d28-4d97-8704-c56c44e04a62depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$83ab9733-5969-4d0c-a3c0-b8f4d2402fdequeued¤logsrunning¦outputbodyP mimetext/htmlrootassigneelast_run_timestampA}Q persist_js_state·has_pluto_hook_features§cell_id$83ab9733-5969-4d0c-a3c0-b8f4d2402fdedepends_on_disabled_cells§runtimeZ published_object_keysdepends_on_skipped_cells§errored±cell_dependencies$334abd5f-8a2c-4e05-96cc-feb9dd8f30aeprecedence_heuristic cell_id$334abd5f-8a2c-4e05-96cc-feb9dd8f30aedownstream_cells_mapupstream_cells_map@md_strgetindex$afe988c7-c708-4fdb-bf82-54edeb9db708precedence_heuristic cell_id$afe988c7-c708-4fdb-bf82-54edeb9db708downstream_cells_mapupstream_cells_maptodayDates$83ab9733-5969-4d0c-a3c0-b8f4d2402fdeDates.format|>@dateformat_strMarkdown$c78da21b-40ad-42d1-8516-b91d16982c77precedence_heuristic cell_id$c78da21b-40ad-42d1-8516-b91d16982c77downstream_cells_mapupstream_cells_map@md_strgetindex$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76dprecedence_heuristic cell_id$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76ddownstream_cells_mapupstream_cells_map@md_strgetindex$09abe51d-ed7d-4f8a-b49c-193dbf188e02precedence_heuristic cell_id$09abe51d-ed7d-4f8a-b49c-193dbf188e02downstream_cells_mapupstream_cells_map@md_strgetindex$0659caa1-1dfd-418a-80c8-3167ca30ade9precedence_heuristic cell_id$0659caa1-1dfd-418a-80c8-3167ca30ade9downstream_cells_mapupstream_cells_map@md_strgetindex$12928360-90aa-4409-860a-af7f5c781e98precedence_heuristic cell_id$12928360-90aa-4409-860a-af7f5c781e98downstream_cells_mapupstream_cells_map@md_strgetindex$8e6406dd-e58c-4aef-8bc9-a57984f90884precedence_heuristic cell_id$8e6406dd-e58c-4aef-8bc9-a57984f90884downstream_cells_mapupstream_cells_map@md_strgetindex$70b70576-0c49-4e5b-b7c1-dd400f3fbccaprecedence_heuristic cell_id$70b70576-0c49-4e5b-b7c1-dd400f3fbccadownstream_cells_mapupstream_cells_map@md_strgetindex$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7precedence_heuristic cell_id$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7downstream_cells_mapupstream_cells_map@md_strgetindex$c74cace1-0e96-48e7-82d3-12f3af3d8591precedence_heuristic cell_id$c74cace1-0e96-48e7-82d3-12f3af3d8591downstream_cells_mapupstream_cells_map@md_strgetindex$50f84dd5-7585-482d-bd8e-96b6cabfdbc2precedence_heuristic cell_id$50f84dd5-7585-482d-bd8e-96b6cabfdbc2downstream_cells_mapupstream_cells_map@md_strgetindex$a1ec03ac-f7b4-4499-92e2-c2a047ed3574precedence_heuristic cell_id$a1ec03ac-f7b4-4499-92e2-c2a047ed3574downstream_cells_mapupstream_cells_map@md_strgetindex$d8ba51b9-2d28-4d97-8704-c56c44e04a62precedence_heuristic cell_id$d8ba51b9-2d28-4d97-8704-c56c44e04a62downstream_cells_mapupstream_cells_map@md_strgetindex$83ab9733-5969-4d0c-a3c0-b8f4d2402fdeprecedence_heuristiccell_id$83ab9733-5969-4d0c-a3c0-b8f4d2402fdedownstream_cells_mapDates$afe988c7-c708-4fdb-bf82-54edeb9db708PlutoUIHypertextLiteralupstream_cells_mapTableOfContentscell_execution_order$83ab9733-5969-4d0c-a3c0-b8f4d2402fde$afe988c7-c708-4fdb-bf82-54edeb9db708$c78da21b-40ad-42d1-8516-b91d16982c77$c74cace1-0e96-48e7-82d3-12f3af3d8591$70b70576-0c49-4e5b-b7c1-dd400f3fbcca$12928360-90aa-4409-860a-af7f5c781e98$d8ba51b9-2d28-4d97-8704-c56c44e04a62$09abe51d-ed7d-4f8a-b49c-193dbf188e02$8e6406dd-e58c-4aef-8bc9-a57984f90884$334abd5f-8a2c-4e05-96cc-feb9dd8f30ae$0659caa1-1dfd-418a-80c8-3167ca30ade9$50f84dd5-7585-482d-bd8e-96b6cabfdbc2$a1ec03ac-f7b4-4499-92e2-c2a047ed3574$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76dlast_hot_reload_timeshortpath1-4: Functions.jlprocess_statusreadypath?/home/runner/work/workshop/workshop/notebooks/1-4: Functions.jlpluto_versionv0.20.24last_save_timeA}Q~-cell_order$afe988c7-c708-4fdb-bf82-54edeb9db708$c78da21b-40ad-42d1-8516-b91d16982c77$c74cace1-0e96-48e7-82d3-12f3af3d8591$70b70576-0c49-4e5b-b7c1-dd400f3fbcca$12928360-90aa-4409-860a-af7f5c781e98$d8ba51b9-2d28-4d97-8704-c56c44e04a62$09abe51d-ed7d-4f8a-b49c-193dbf188e02$8e6406dd-e58c-4aef-8bc9-a57984f90884$334abd5f-8a2c-4e05-96cc-feb9dd8f30ae$0659caa1-1dfd-418a-80c8-3167ca30ade9$50f84dd5-7585-482d-bd8e-96b6cabfdbc2$a1ec03ac-f7b4-4499-92e2-c2a047ed3574$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76d$83ab9733-5969-4d0c-a3c0-b8f4d2402fdepublished_objectsnbpkginstall_time_nsÿ ìinstantiatedòinstalled_versionsDatesstdlibPlutoUI0.7.76HypertextLiteral0.9.5terminal_outputsDates Waiting for other notebooks to finish Pkg operations... === Resolving... ===  Installed PlutoUI ─ v0.7.76  Project No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Project.toml`  Updating `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Manifest.toml` [14a3606d] ↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4 Instantiating... === Precompiling... === Waiting for notebook process to start... Done. Starting precompilation... nbpkg_sync Waiting for other notebooks to finish Pkg operations... === Resolving... ===  Installed PlutoUI ─ v0.7.76  Project No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Project.toml`  Updating `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Manifest.toml` [14a3606d] ↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4 Instantiating... === Precompiling... === Waiting for notebook process to start... Done. Starting precompilation... PlutoUI Waiting for other notebooks to finish Pkg operations... === Resolving... ===  Installed PlutoUI ─ v0.7.76  Project No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Project.toml`  Updating `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Manifest.toml` [14a3606d] ↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4 Instantiating... === Precompiling... === Waiting for notebook process to start... Done. Starting precompilation... HypertextLiteral Waiting for other notebooks to finish Pkg operations... === Resolving... ===  Installed PlutoUI ─ v0.7.76  Project No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Project.toml`  Updating `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ptpwpmhwjv/Manifest.toml` [14a3606d] ↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4 Instantiating... === Precompiling... === Waiting for notebook process to start... Done. Starting precompilation... enabled÷restart_recommended_msgrestart_required_msgbusy_packageswaiting_for_permission,waiting_for_permission_but_probably_disabled«cell_inputs$334abd5f-8a2c-4e05-96cc-feb9dd8f30aecell_id$334abd5f-8a2c-4e05-96cc-feb9dd8f30aecodeumd""" ## 1: Function Syntax (Multi-line & Defaults) !!! warning "" * **Basic Multi-line:** Define a function `calculate_vol(l, w, h)` using the `function ... end` block. It should return the product of the three arguments. - Test: `calculate_vol(2, 3, 4)` should be 24. * **Adding Defaults:** Redefine the function so `h` has a default value of `4`. - Code: `function calculate_vol(l, w, h=1) ... end` * **Testing Defaults:** Call `calculate_vol(5, 5)`. - Note: You only provided 2 arguments, so Julia automatically supplies `4` for `h`, yielding 100 for the result; what will `calculate_vol(5, 5, 5)` produce? """metadatashow_logsèdisabled®skip_as_script«code_folded$afe988c7-c708-4fdb-bf82-54edeb9db708cell_id$afe988c7-c708-4fdb-bf82-54edeb9db708codeu""" !!! note "1-4: Functions" **Last Updated: $(Dates.format(today(), dateformat"d u Y"))** """ |> Markdown.parsemetadatashow_logsèdisabled®skip_as_script«code_folded$c78da21b-40ad-42d1-8516-b91d16982c77cell_id$c78da21b-40ad-42d1-8516-b91d16982c77code~md""" # Functions in Julia Introduction to the contruction of Julia functions and their implementation by Julia. If you come from Python or Java, functions are attached to classes. In Julia, functions are standalone citizens, and they define the behavior of the language. We will cover the syntax, the argument system, and introduce a key Julia feature: **multiple dispatch**. """metadatashow_logsèdisabled®skip_as_script«code_folded$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76dcell_id$88e1c20b-5f1d-4a9c-8c4f-61ed72ebc76dcodemd""" ## 6: Function Broadcasting !!! warning "" * Create a function to add and multiply three scalars. * Execute the function for three scalar values. * Construct three vectors of equal length. * Execute the function using those three vectors. * What happens? * Execute the same function, but append a `.` after the name and before the opening parenthesis. - E.g., myfunc.(...) * What happens now? """metadatashow_logsèdisabled®skip_as_script«code_folded$09abe51d-ed7d-4f8a-b49c-193dbf188e02cell_id$09abe51d-ed7d-4f8a-b49c-193dbf188e02codemd""" # Summary !!! note "" * Three versions of function definitions: multi-line blocks, one-liners, or anonymous (lambdas). * Positional and keyword arguments are separated by a `;`. * Positional arguments are required. Keyword arguments are optional. * Multiple Dispatch is used to determine the correct function to execute, making the language composable and highly performant. """metadatashow_logsèdisabled®skip_as_script«code_folded$0659caa1-1dfd-418a-80c8-3167ca30ade9cell_id$0659caa1-1dfd-418a-80c8-3167ca30ade9code+md""" ## 2: Keywords & Single-liners !!! warning "" * **Keywords (`:` vs `;`):** Define a function `describe_data(data; label="Unknown")`. - Note the semicolon `;`! This separates positional arguments (`data`) from keyword arguments (`label`). - Make the function return a string: `"$label: $data"`. * **Usage:** - Call it without the keyword: `describe_data([10, 20])`. - Call it *with* the keyword: `describe_data([10, 20], label="Temperature")`. * **The One-Liner:** Redefine this function in one line (without needing `function`.) """metadatashow_logsèdisabled®skip_as_script«code_folded$12928360-90aa-4409-860a-af7f5c781e98cell_id$12928360-90aa-4409-860a-af7f5c781e98code md""" # Multiple Dispatch !!! note "The most important part and a core reason for Julia's existence." ## Single Dispatch Object-oriented languages such as Python and Java use single dispatch for choosing the function or method to execute. That means that the function is determined using the function name and the type of the first argument. This is called **single dispatch**. Therefore, the functions or methods are tightly bound to the object or class. When you call `obj.method(arg)`, the language transforms that expression into `method(obj, arg)`. Single dispatch creates the **Expression Problem**. For example, `a + b` calls `a.__add__(b)` in Python. If the object `a` is known, but not `b`, there is no problem; the `__add__` function can still be called. However, if `a` is unknown, what do we do now? In Python this problem is solved by the `__radd__` function. Python will try `__add__`, if that fails, then it will try `__radd__`. Therefore, when we add an `__add__` operator to a new class in Python, the new class must implement the `__radd__` method too, because other classes do not know about our new classs. ## Multiple Dispatch Julia is not an object-oriented language. It is functional language. When you call `func(arg1, arg2)`, Julia looks at the types of the function's positional arguments to determine the version of the function to execute. This is called **multiple dispatch**. Julia will look at the argument types of all positional arguments, i.e., `arg1` and `arg2`, and choose the function that has that exact type signature. Multiple dispatch makes it easier for a new Julia type to extend the functional interface of another type. The example below illustrates that situation. Two `fAdd` functions are implemented, one for each situation. Julia then determines which version of that function to execute. The situation is similar to Python's `__add__` and `__radd__`, except that Python first tries to use `__add__` and when that fails, tries `__radd__`. Whereas, Julia just chooses the correct function the first time. The following is an example of how Julia may implement this situation. ```julia-repl julia> # Define additon for an integer and a float, and the other way around: julia> fAdd(a::Int, b::Float64) = a + b julia> fAdd(a::Float64, b::Int) = a + b ``` Why is this powerful? 1. Symmetry: You don't need __radd__ because compared with (a::Float, b::Int), (a::Int, b::Float) is just a different method. 2. Extensibility: If you import a library that defines a `Planet` type, and another library that defines a `Satellite` type, you can define a `collide(p::Planet, s::Satellite)` function in your own code without modifying the source code of either library. 3. Trying to add two integers or two floating points fails, e.g., "ERROR: MethodError: no method matching fAdd(::Float64, ::Float64)." If you know, for example, that a particular function is only supposed to be called with an integer and a float, and you don't want to worry about the order, you now have a check on your code. """metadatashow_logsèdisabled®skip_as_script«code_folded$8e6406dd-e58c-4aef-8bc9-a57984f90884cell_id$8e6406dd-e58c-4aef-8bc9-a57984f90884codeٜmd""" # Problems !!! tip "Remember that you can get help either through `?` in a REPL or with "Live Docs" right here in Pluto (lower right-hand corner)" """metadatashow_logsèdisabled®skip_as_script«code_folded$70b70576-0c49-4e5b-b7c1-dd400f3fbccacell_id$70b70576-0c49-4e5b-b7c1-dd400f3fbccacodemd""" # Function Arguments ## Positional and Keyword Functions have two types of arguments, positional and keyword. They are separated using a '`;`' (semi-colon). Positional arguments are required, whereas keyword arguments are optional. The next section will show the importance of positional arguments. ```julia-repl julia> # a and b are positional, while scale and offset are keywords julia> function transform(a, b; scale=1.0, offset=0.0) return (a + b) * scale + offset end julia> # Usage julia> transform(10, 20; scale=2.0) ``` ## Default Values and Methods Positional arguments can have default values, which means the default value will be used if the argument is missing. ```julia-repl julia> # This function defines a default value for the y. julia> myfunc(x, y=10) = x * y ``` Julia creates two versions or methods of this function, one with two arguments and one with one argument. ```julia-repl julia> myfunc(x, y) julia> myfunc(x) # The 2nd positional argument will have the value 10. ``` """metadatashow_logsèdisabled®skip_as_script«code_folded$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7cell_id$0eec43c3-6ca7-4d11-b21c-7d661ef0a3e7codeRmd""" ## 5: Specialization & Dispatch !!! warning "" * **Specific Definition:** add a new method to the *same* function name, `my_add`, but constrain the types to Strings only. - `my_add(a::String, b::String) = "$a ... $b"` * **Check Methods:** Run `methods(my_add)` again. You should now see **2 methods**. * **Dispatch in Action:** - Execute `my_add(5, 5)`. (Julia chooses the generic version). - Execute `my_add("A", "B")`. (Julia chooses the specific String version). * **The Rule:** Julia always executes the **most specific** method that matches the arguments provided. """metadatashow_logsèdisabled®skip_as_script«code_folded$c74cace1-0e96-48e7-82d3-12f3af3d8591cell_id$c74cace1-0e96-48e7-82d3-12f3af3d8591codemd""" # Defining Functions Julia offers three syntactic ways to define a function. They all compile down to the same code, so choose the syntax that is most convenient or appropriate. ## Default Syntax The standard multi-line version looks similar to other languages. It uses the `function` statement and closes with the `end` statement. ```julia-repl julia> function hypotenuse(a, b) result = sqrt(a^2 + b^2) return result end ``` !!! note * Julia does not use indentation to define code blocks. It is used for readability. * Julia automatically returns the result of the last expression. Therefore, the `return` statement is optional for the last line of a function. ## Single-Line Syntax The single-line assignment form may be unique to Julia and is perfect for short operations. While functionally identical to the multiline version, it reduces visual clutter for simple logic. ```julia-repl julia> hypotenuse(a, b) = sqrt(a^2 + b^2) ``` !!! note The compiler will automatically inline functions to improve performance, unlike C or Python. Therefore, there is no performance hit by using functions and their use is encouraged for convenience and readability. ## Anonymous Functions (Lambdas) An anonymous function uses the arrow syntax: `->`. The variables before the `->` are the arguments to be used and the expression afterward is the function body. They are often used in functional programming contexts such as `map`, `filter` or `findall` to define a filter. ```julia-repl julia> # Equivalent to Python's: lambda x: x^2 + 2x - 1 julia> f = x -> x^2 + 2x - 1 julia> # Usage in a map function julia> map(x -> x^2, [1, 2, 3]) julia> # Two arrays zipped together returning a Tuple with two values. julia> map(((x, y),) -> x > 2 && y > 4, zip(1:5, 2:6)) ``` """metadatashow_logsèdisabled®skip_as_script«code_folded$50f84dd5-7585-482d-bd8e-96b6cabfdbc2cell_id$50f84dd5-7585-482d-bd8e-96b6cabfdbc2codemd""" ## 3: Anonymous Functions (Map & Filter) !!! warning "" * **The Syntax:** An anonymous function (lambda) looks like `x -> x + 1`. * **Map:** Use `map()` with an anonymous function to double every number in the list `[1, 2, 3, 4]`. - Structure: `map(func, collection)`. * **Filter:** Use `filter()` with an anonymous function to extract numbers greater than 5 from the list `[3, 4, 5, 6, 7]`. """metadatashow_logsèdisabled®skip_as_script«code_folded$a1ec03ac-f7b4-4499-92e2-c2a047ed3574cell_id$a1ec03ac-f7b4-4499-92e2-c2a047ed3574codemd""" ## 4: The Generic `add()` !!! warning "" * **Generic Definition:** Define a function `my_add(a, b) = a + b`. Do not add any `::Type` annotations. * **Duck Typing:** - Try `my_add(10, 20)` (Integers). - Try `my_add(3.14, 2.0)` (Floats). - Try `my_add("Hello ", "World")` (Strings). - *Observation:* It works for all of them because the underlying `+` is defined for all these types. * **Introspection:** Run `methods(my_add)`. - You should see `# 1 method for generic function "my_add"`. """metadatashow_logsèdisabled®skip_as_script«code_folded$d8ba51b9-2d28-4d97-8704-c56c44e04a62cell_id$d8ba51b9-2d28-4d97-8704-c56c44e04a62codemd""" !!! note "Summary of Dispatch" - Python: `dog.bark(at_stranger)` -> Logic lives in `dog`.\ - Julia: `bark(dog, stranger)` -> Logic lives in the `bark` function, selected specifically for the combination of `Dog` and `Stranger`. """metadatashow_logsèdisabled®skip_as_script«code_folded$83ab9733-5969-4d0c-a3c0-b8f4d2402fdecell_id$83ab9733-5969-4d0c-a3c0-b8f4d2402fdecodegbegin using Dates, PlutoUI, HypertextLiteral TableOfContents(title = "1-4: Functions", depth = 4) endmetadatashow_logsèdisabled®skip_as_script«code_foldedënotebook_id$52260626-45be-11f1-bceb-7d76484c3ecfin_temp_dir¨metadata